package app;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import controller.ClientListener;
import dao.DaoException;
import dao.DaoFactory;
import model.Client;
import model.Email;
import model.ModelException;
import model.Server;

public class Init {

	/**
	 * @param args
	 * @throws DaoException 
	 * @throws IOException
	 */
	public static void main(String[] args){

		
		Server server = new Server();

		ServerSocket serverSocket = null;
		try {
			serverSocket = new ServerSocket(server.getPort());
			System.out.println("--- SERVER STARTED ---");
			
		} catch (IOException e) {
			System.out.println("Server: Could not start server socket, exiting...");
			System.exit(0);
		}

		while (true) {

			Socket clientSocket;
			try {
				
				// A client connects
				clientSocket = serverSocket.accept();
				
				// Create the client object
				Client client = new Client(clientSocket);
				
				String name = (String) client.getInStream().readObject();
				client.setName(name);
				
				System.out.println("Server: Connected with " + name);

				server.addOrUpdate(client);
				
				// Send all the emails for this user
				ArrayList<Email> emailsList = server.getPendingEmailsFor(name);
				if (emailsList.size() > 0){
					client.getOutStream().writeObject(new String("emails"));
					client.getOutStream().writeObject(emailsList);
					
					// when the emails are sent, we need to update 
					List<Email> emailsToDestroy = new ArrayList<Email>();
					List<Email> emailsToUpdate = new ArrayList<Email>();

					Iterator<Email> it = emailsList.iterator();
					while(it.hasNext()){
					    Email em = it.next();
					    em.removePendingRecepient(name);
					    if (em.hasNoMorePendingRecepients()){
					    	emailsToDestroy.add(em);
					    } else {
					    	emailsToUpdate.add(em);
					    }
					}
					
					try {
						if (emailsToDestroy.size() > 0){
//							System.out.println("Some emails are there to be destroyed...");
							server.destroyEmails(emailsToDestroy);
						}
						if (emailsToUpdate.size() > 0){
//							System.out.println("Some emails are there to be updated, which are:");
//							for(Email e : emailsToUpdate){
//								System.out.println(e.toString());
//							}
							server.updateEmails(emailsToUpdate);
						}
					} catch (DaoException | ModelException e) {
						System.out.println("Server: Error, could not update/delete emails just sent");
					}
					
				}
				
				// Start listener thread
				new Thread(new ClientListener(client, server)).start();

			} catch (IOException e) {
				e.printStackTrace();
			} catch (ClassNotFoundException e) {
				e.printStackTrace();
			}

		}

	}



}
